/*-------------------------------------------------------------------------

***************** Modification History ***********************************
   @doc
   @module shift.c - Shift operation functions |
   @end

**************************************************************************

   Copyright (C) 1999 by VeriFone, Inc.

   All rights reserved.  No part of this software may be reproduced,
   transmitted, transcribed, stored in a retrieval system, or translated
   into any language or computer language, in any form or by any means,
   electronic, mechanical, magnetic, optical, chemical, manual or otherwise,
   without the prior written permission of VeriFone, Inc.

---------------------------------------------------------------------------*/
#include <project.h>

#ifdef SHIFT_DEFINED


#include <aclconio.h>
#include <stdio.h>
#include <stdlib.h>
#include <applidl.h>
#include <svctxo.h>
#include <dbmgr.h>
#include <formater.h>
#include <string.h>
#include <actutil.h>


#ifdef DEBUG_VSOPREPT
#define DEBUG_95
#endif
#include <accum.h>
#include <define.h>
#include <transact.h>
#include <mdlfuncs.h>
#include <funcids.h>
#include <operate.h>
#include <oper.h>
#include <sdt.h>
#include <shift.h>
#include <shftform.h>
#include <pbatch.h>
#include <gds.h>
#include <ui.h>
#include <msg.h>
#include <msgfuncs.h>
#include <msgshf.h>
#include <confio.h>
#include <bdt.h>
#include <cdt.h>
#include <hdt.h>
#include <tblutil.h>
#include <lct.h>
#include <mit.h>
#include <tct.h>
#include <pct.h>
#include <table.h>
#include <udt.h>
#include <clerk.h>
#include <clrkrpts.h>
#include <spdebug.h>
#include <settle.h>
#include <print.h>
#include <form.h>
#include <form2.h>
#include <date.h>
#include <entry.h>
#include <list.h>
#include <report.h>
#include <pfr.h>
#include <lct.h>
#include <format.h>
#include <merch.h>
#include <pscalls.h>
#include <trt.h>
#include <codesec.h>


FUNCTION_TABLE srShiftFuncs[] = {
    {inShiftProcessing,       SHIFT_PROCESSING},
    {inShiftAllRpts,          PRINT_ALL_SHIFTS_REPORT},
    {inUpdateShiftFlow,       UPDATE_SHIFT},
    {0,                       END_OF_FUNC_TABLE},

};

/*********************************************************************************************
* @func int | inAddShiftFunctions |
*       Adds SHIFT functions to the flexi record.
*
* @rdesc return values.
* @flag int    |  VS_ERR, VS_ESCAPE or VS_SUCCESS
* @end
**********************************************************************************************/

int inAddShiftFunctions(void) {
    int inCount = 0;

    /* Add Shift functions to the flexi record */
    do {
        if (inAddFunctionPointer(srShiftFuncs[inCount].inFieldID, srShiftFuncs[inCount].pinFunction) == VS_ERR)
            return (VS_ERR);
        inCount++;
    } while (srShiftFuncs[inCount].inFieldID != END_OF_FUNC_TABLE);

    return(VS_SUCCESS);
}


/*********************************************************************************************
* @func int | inShiftProcessing |
*       Adds SHIFT functions to the flexi record.
*
*       Handle Shift Processing Functionality
*                   Shift Type == 0 (None) error
*                              == 1 (Auto) edit SDT
*                              == 2 (Manual) increment Shift #
*
*       Globals : Shift Table (SDT) or Shift # in TCT
* @rdesc return values.
* @flag int    |  BRANCH_EXIT
* @end
**********************************************************************************************/

int inShiftProcessing() {
    signed int inChoice;
    char szMessage[MESSAGE_SIZE + 1];
    char szLocBuf[5 + 1];
    char* chNull = 0;

    /*
     *      Error if Shift processing not enabled (0),
     *      Edit SDT if Shift processing is auto (1),
     *      Increment Shift # if Shift processing is manual (2).
     */
    switch (inGetShiftType()) {
    case NO_SHIFT:
        vdDisplayMessageFromFile(SHIFT_ERR_MSG21, ERROR_MSG);
        break;

    case AUTO_SHIFT:
        strncpy(szLocBuf, pchGetMessage(SDT_FILENAME), 5);
        szLocBuf[5] = NULL_CH;
        inConfRecEdit(szLocBuf);
        break;

    case MANUAL_SHIFT:
        /*
         *      Give Increment Choice
         */
        if ((inChoice = obDisp.inDO_ChooseOne(chNull, pchGetMsg(INC_SHIFT_MSG15), pchGetMsg(YESNO_MSG5x), 2, NULL_PFI)) == KEY_YES) {
            if (inLoadTCTRec(0) == VS_SUCCESS) {
                vdSetCurrentShift((char) ((chGetCurrentShift() >= '9' ? '1' : chGetCurrentShift() + 1)));
                if (inSaveTCTRec(0) != VS_SUCCESS) {
                    inChoice = VS_ERR;
                    vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
                }
            } else {
                inChoice = VS_ERR;
                vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
            }
        }
        /*
         *      No to increment check on Reset.
         */
        else if (inChoice == KEY_NO) {
            if ((inChoice = obDisp.inDO_ChooseOne(chNull, pchGetMsg(RESET_SHIFT_MSG15), pchGetMsg(YESNO_MSG5x), 2, NULL_PFI)) == KEY_YES) {
                if (inLoadTCTRec(0) == VS_SUCCESS) {
                    vdSetCurrentShift('1');
                    if (inSaveTCTRec(0) != VS_SUCCESS) {
                        inChoice = VS_ERR;
                        vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
                    }
                } else {
                    inChoice = VS_ERR;
                    vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
                }
            }
        }
        /*
         *      Display Current Shift Value in TCT if no error
         */
        if (inChoice != VS_ERR) {
            vdGetMessageFromFile(SHIFT_NUM_IS_MSG12, szMessage);
            szMessage[11] = chGetCurrentShift();
            vdDisplayStatusString(szMessage);
            vdDelay(ERR_MSG_DELAY);
        }
        break;
    }

    return(BRANCH_EXIT);
} /* End of inShiftProcessing () */



/*********************************************************************************************
* @func int | inShiftAllRpts |
*       Print All Shifts Report
*
*
* @rdesc return values.
* @flag int    |  BRANCH_EXIT
* @end
**********************************************************************************************/

int inShiftAllRpts(TRANSACTION_OBJECT* pobTran) {
    if (inGetPrinterType() != NOPRINTER && fGetEnablePrinter()) {
        if (inGetShiftType() == NO_SHIFT) {
            vdDisplayMessageFromFile(SHIFT_ERR_MSG21, ERROR_MSG);
            return (BRANCH_EXIT);
        }

        inGetShiftTemplate();

        inPrintAllShiftReport(&obPrinter, pobTran);
    }

    return (BRANCH_EXIT);
} /* End of inShiftAllRpts () */


/*********************************************************************************************
* @func int | inPrintAllShiftReport |
*       Print All Shifts Report
*
*
* @rdesc return values.
* @flag int    |  VS_ERR on error and VS_SUCCESS on success
* @end
**********************************************************************************************/
int inPrintAllShiftReport(PRINTER_OBJECT* obPrinter,TRANSACTION_OBJECT* pobTran) {
    int inShift = 0;
    int inNeedHeader = VS_TRUE;

    STT_REC srSTTRec;
    STT_KEY srSTTKey;
    char szSTTFileName[FILENAME_SIZE + 1] ;
    DB_FILE srDBFPtr;
    int inRetVal;
    char chShift;
    SHIFT_TOTS_REC srShiftTots;
    SHIFT_TOTS_REC srGrandTots;
    int inStart,
    inStop,
    inNumberOfMerchants,
    inMerch = 0;
    int inHostIndex;
    int inNeedGrTot;
    int inShiftCnt;

    memset((char *) &srGrandTots, 0x00, (SIZE_SHIFT_TOTS_REC));
    inNumberOfMerchants = inSelectOneAllMID(pobTran, fGetMultiMerchPrompt());
    if (inNumberOfMerchants == 0)
        return (VS_SUCCESS);

    if (inNumberOfMerchants == inGetMITTotRecs()) {
        inStart = 1;
        inStop = inGetMITTotRecs();
    } else if (inNumberOfMerchants == 1) {
        inStart = inGetMerchantNum();
        inStop = inGetMerchantNum();
    } else {
        inStart = 1;
        inStop = 0;
    }

    inNeedGrTot = 0;
    for (inShift = 0; inShift < SHIFT_ARRAY_SIZE; inShift++) {
        chShift = (char) (inShift + 0x30);
        memset((char *) &srShiftTots, 0x00, SIZE_SHIFT_TOTS_REC);
        inShiftCnt = 0;

        for (inMerch = inStart; inMerch <= inStop; inMerch++) {
            if (inLoadMITRec(inMerch - 1) != VS_SUCCESS)
                return(VS_ERR);

            /* open correct merchant batch */
            if (inGetDCBatchRecCnt(pobTran) == 0)
                continue;

            for (inHostIndex = 0; inHostIndex < MAX_HOSTS; inHostIndex++) {
                /*vdSetCDTHostIndex(inHostIndex); ALVARO*/
                //              vdSetHostHandle(inHostIndex);
                /* if MIT record not already loaded, load first merchant record */
                if (inGetMerchantNum() == 0)
                    inLoadMITRec(0);

                if (inLoadDefaultHost(inHostIndex) != VS_SUCCESS)
                    return (VS_ERR);

                if (inLoadDefaultCurrency(pobTran) != VS_SUCCESS)
                    return (VS_ERR);

                /* Only print the report for independent host */
                if (!fGetIndependentBatch())
                    continue;

                vdGetSTTFileName(szSTTFileName);
                if (inOpenSTT(&srDBFPtr, szSTTFileName) < 0)
                    continue;

                srSTTKey.chShift = chShift;
                memset((char *) &srSTTRec, 0x00, (SIZE_STT_REC));

                inRetVal = inGetKeySTTRec(&srDBFPtr, &srSTTRec, &srSTTKey, KEY_SHIFT, DB_FIRST);
                if (inRetVal != VS_ERROR)
                    do {
                        /* shift line totals */
                        srShiftTots.inCount += srSTTRec.inNetCount;
                        srShiftTots.lnTotAmt += srSTTRec.lnNetTotAmt;
                        srShiftTots.lnBaseAmt += srSTTRec.lnNetBaseAmt;
                        /* srShiftTots.lnTaxAmt += srSTTRec.lnNetTaxAmt; */
                        srShiftTots.lnTipAmt += srSTTRec.lnNetTipAmt;
                        srShiftTots.lnCashBack += srSTTRec.lnNetCashBack;
                        /* srShiftTots.lnSurcharge += srSTTRec.lnNetSurcharge; */

                        /* Grand all Shift Total section */
                        srGrandTots.inCount += srSTTRec.inNetCount;
                        srGrandTots.lnTotAmt += srSTTRec.lnNetTotAmt;
                        srGrandTots.lnBaseAmt += srSTTRec.lnNetBaseAmt;
                        srGrandTots.lnTaxAmt += srSTTRec.lnNetTaxAmt;
                        srGrandTots.lnTipAmt += srSTTRec.lnNetTipAmt;
                        srGrandTots.lnCashBack += srSTTRec.lnNetCashBack;
                        srGrandTots.lnSurcharge += srSTTRec.lnNetSurcharge;

                        srSTTKey.chShift = chShift;
                        memset((char *) &srSTTRec, 0x00, (SIZE_STT_REC));
                        inRetVal = inGetKeySTTRec(&srDBFPtr, &srSTTRec, &srSTTKey, KEY_SHIFT, DB_NEXT);
                        inShiftCnt++;
                    } while (inRetVal != VS_ERR);

                inCloseSTT(&srDBFPtr);
            }/* End of Host Loop */
        }/* End of Merchant Loop */


        if (inShiftCnt > 0) {
            if (inNeedHeader == VS_TRUE) {
                if (fGetEnablePrinter())
                    vdDisplayMessageFromFile(PRINTING_MSG, STATUS_MSG);

                vdMakeReportHeader(pobTran);
                /* We probably will not have Multi merchants and shifts. If we do we will
                    not print the header as it will reflect the last merchant and the shift
                    report is for all merchants together. */
                if (inGetMITTotRecs() == 1 || inNumberOfMerchants == 1)
                    inPrintReptHeader(pobTran, obPrinter);
                else {
                    if (inPrintLines(obPrinter, REPT_HEADER_START, REPT_HEADER_END, NO_BL_LINE, lnHeaderCondition) != VS_SUCCESS)
                        return(VS_ERR);
                }

                vdSetAllShiftHeaderCondition();
                if (inPrintLines(obPrinter, ALL_SHIFT_TOP_START, ALL_SHIFT_TOP_END, NO_BL_LINE, lnHeaderCondition) != VS_SUCCESS)
                    return(VS_ERR);
                inNeedHeader = VS_FALSE;
            }

            srSTTRec.inNetCount = srShiftTots.inCount;
            srSTTRec.lnNetTotAmt = srShiftTots.lnTotAmt;
            srSTTRec.lnNetBaseAmt = srShiftTots.lnBaseAmt;
            srSTTRec.lnNetTipAmt = srShiftTots.lnTipAmt;
            srSTTRec.lnNetCashBack = srShiftTots.lnCashBack;

            if (inPrintAllShiftRecord(obPrinter, srSTTRec, inShift) != VS_SUCCESS)
                return(VS_ERROR);
            if (act_kbd_pending_test(KEY_CANCEL))
                return(VS_ESCAPE);

            inNeedGrTot++;
        }
    }

    /* print Shifts Grand Total */
    if (inNeedGrTot > 0) {
        sprintf(srRcpt.unFrm.srSubTotal.srTerm.szCreditTotal, SUBSTITUTE_LD, srGrandTots.lnBaseAmt);
        sprintf(srRcpt.unFrm.srSubTotal.srTerm.szTipTotal, SUBSTITUTE_LD, srGrandTots.lnTipAmt);
        sprintf(srRcpt.unFrm.srSubTotal.srTerm.szCashBack, SUBSTITUTE_LD, srGrandTots.lnCashBack);
        sprintf(srRcpt.unFrm.srSubTotal.srTerm.szTotalSchgAmt, SUBSTITUTE_LD, srGrandTots.lnSurcharge);
        sprintf(srRcpt.unFrm.srSubTotal.srTerm.szTaxTotal, SUBSTITUTE_LD, srGrandTots.lnTaxAmt);
        sprintf(srRcpt.unFrm.srSubTotal.srTerm.szNetTotal, SUBSTITUTE_LD, srGrandTots.lnTotAmt);
        vdFormatAmount(srRcpt.unFrm.srSubTotal.srTerm.szCreditTotal, VS_TRUE);
        vdFormatAmount(srRcpt.unFrm.srSubTotal.srTerm.szTipTotal, VS_TRUE);
        vdFormatAmount(srRcpt.unFrm.srSubTotal.srTerm.szCashBack, VS_TRUE);
        vdFormatAmount(srRcpt.unFrm.srSubTotal.srTerm.szTotalSchgAmt, VS_TRUE);
        vdFormatAmount(srRcpt.unFrm.srSubTotal.srTerm.szTaxTotal, VS_TRUE);
        vdFormatAmount(srRcpt.unFrm.srSubTotal.srTerm.szNetTotal, VS_TRUE);

        vdSetAllShiftBottomCondition(pobTran, &srGrandTots);
        if (inPrintLines(obPrinter, ALL_SHIFT_BOTTOM_START, ALL_SHIFT_BOTTOM_END, NO_BL_LINE, lnBottomCondition) != VS_SUCCESS)
            return(VS_ERR);
    }
    if (inNeedHeader == VS_TRUE) {
        vdDisplayMessageFromFile(BATCH_EMPTY_MSG, WARNING_MSG);
        return(VS_ERR);
    }

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | vdSetAllShiftHeaderCondition |
*       Set conditions for header of all shifts report
*
*
* @rdesc return values.
* @flag int    |  no return value
* @end
**********************************************************************************************/


void vdSetAllShiftHeaderCondition() {
    if (inGetPrinterType() == NOPRINTER || !fGetEnablePrinter())
        return;

    lnHeaderCondition = formater_set_flags(0, (fGetDemoMode() == VS_TRUE), 0, 0, (inGetApplicationType() == RESTAURANT), (inGetApplicationType() == RETAIL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (inGetTipProcessing() == TIP_OFF && !(fGetCashBack())), (inGetTipProcessing() > TIP_OFF && !(fGetCashBack())),
        (inGetTipProcessing() == TIP_OFF && (fGetCashBack())),
        (inGetTipProcessing() > TIP_OFF && (fGetCashBack())),

        0,
        (inGetTipProcessing() > TIP_OFF && (fGetCashBack())),
        (inGetTipProcessing() == TIP_OFF && (fGetCashBack())),
        (inGetTipProcessing() > TIP_OFF && !(fGetCashBack())), -1);
}

/*********************************************************************************************
* @func int | vdSetAllShiftMiddleCOndition |
*       Set conditions for middle of all shifts report
*
*
* @rdesc return values.
* @flag int    |  no return value
* @end
**********************************************************************************************/


void vdSetAllShiftMiddleCondition() {
    if (inGetPrinterType() == NOPRINTER || !fGetEnablePrinter())
        return;

    lnMiddleCondition = formater_set_flags(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (inGetTipProcessing() > TIP_OFF && (fGetCashBack())),
        (inGetTipProcessing() > TIP_OFF && !(fGetCashBack())),
        (inGetTipProcessing() == TIP_OFF && (fGetCashBack())),
        (inGetTipProcessing() == TIP_OFF && !(fGetCashBack())), -1);
}


/*********************************************************************************************
* @func int | vdSetAllShiftBottomCondition |
*       Set conditions for bottom of all shifts report
*
*
* @rdesc return values.
* @flag int    |  no return value
* @end
**********************************************************************************************/


void vdSetAllShiftBottomCondition(TRANSACTION_OBJECT* pobTran,SHIFT_TOTS_REC* psrGrandTots) {
    if (inGetPrinterType() == NOPRINTER || !fGetEnablePrinter())
        return;

    lnBottomCondition = formater_set_flags(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (fGetTaxProc() || psrGrandTots->lnTaxAmt > 0),
        (inGetTipProcessing() > TIP_OFF),
        (fGetCashBack()),
        (inGetSurCharge()),

        0,
        0,
        0,
        0, -1);
}

/*********************************************************************************************
* @func int | inUpdateShiftFlow |
*       This routine updates the Shift information if necessary.  It is intended to be used from the TRT.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*
* @rdesc return values.
* @flag int    |  VS_SUCCESS
* @flag int    |  VS_ERR
* @end
**********************************************************************************************/


/* #ifdef BATCH_DEFINED */


int inUpdateShiftFlow(TRANSACTION_OBJECT* pobTran) {
    if (!fGetDataCapture(pobTran))
        return(VS_SUCCESS);

    /* pj1 - skip inUpdateAccum if open tab */
    if (pobTran->fOTBatchOpen)
        return(VS_SUCCESS);
    /* Set the power fail recovery state */
    inPFRStateStoreAll(PFR_BEGIN_UPDATE_SHIFT, pobTran, 1, 0);

    if (inSetSTTAmount(pobTran) != VS_SUCCESS) {
        vdSGErrorMessage(SHIFT_TOTAL_ERR_MSG21);
        /* Set the power fail recovery state */
        inPFRStateStoreAll(PFR_UPDATE_SHIFT_COMPLETE, pobTran, 1, 0);
        return(VS_ERR);
    }

    /* Set the power fail recovery state */
    inPFRStateStoreAll(PFR_UPDATE_SHIFT_COMPLETE, pobTran, 1, 0);

    return(VS_SUCCESS);
}


/*********************************************************************************************
* @func int | inPrintAllShiftRecord |
*       Print All Shifts Report
*
*
* @rdesc return values.
* @flag int    |  VS_ERR, VS_SUCCESS
* @end
**********************************************************************************************/

int inPrintAllShiftRecord(PRINTER_OBJECT* obPrinter,STT_REC srSTTRec,int inShift) {
    char szShift[2];
    szShift[0] = (char) (inShift + 0x30);
    szShift[1] = '\0';
    strcpy(srRcpt.unFrm.srClerk.srMid.szShiftNumber, szShift);
    sprintf(srRcpt.unFrm.srClerk.srMid.szTransCnt, SUBSTITUTE_D, srSTTRec.inNetCount);
    sprintf(srRcpt.unFrm.srClerk.srMid.szTipAmt, SUBSTITUTE_LD, srSTTRec.lnNetTipAmt);
    sprintf(srRcpt.unFrm.srClerk.srMid.szCBackAmt, SUBSTITUTE_LD, srSTTRec.lnNetCashBack);
    sprintf(srRcpt.unFrm.srClerk.srMid.szTransAmt, SUBSTITUTE_LD, srSTTRec.lnNetTotAmt);
    sprintf(srRcpt.unFrm.srClerk.srMid.szBaseAmt, SUBSTITUTE_LD, srSTTRec.lnNetBaseAmt);
    vdFormatAmount(srRcpt.unFrm.srClerk.srMid.szTipAmt, VS_FALSE);
    vdTrimLeadSpaces(srRcpt.unFrm.srClerk.srMid.szTipAmt);
    vdFormatAmount(srRcpt.unFrm.srClerk.srMid.szCBackAmt, VS_FALSE);
    vdTrimLeadSpaces(srRcpt.unFrm.srClerk.srMid.szCBackAmt);
    vdFormatAmount(srRcpt.unFrm.srClerk.srMid.szTransAmt, VS_FALSE);
    vdTrimLeadSpaces(srRcpt.unFrm.srClerk.srMid.szTransAmt);
    vdFormatAmount(srRcpt.unFrm.srClerk.srMid.szBaseAmt, VS_FALSE);
    vdTrimLeadSpaces(srRcpt.unFrm.srClerk.srMid.szBaseAmt);

    vdSetAllShiftMiddleCondition();
    if (inPrintLines(obPrinter, ALL_SHIFT_MIDDLE_START, ALL_SHIFT_MIDDLE_END, NO_BL_LINE, lnMiddleCondition) != VS_SUCCESS)
        return(VS_ERR);

    return(VS_SUCCESS);
}



/*********************************************************************************************
* @func int | inGetShiftTemplate |
*       Set the report template to the active template
*
*
* @rdesc return values.
* @flag int    |  VS_ERR, VS_SUCCESS
* @end
**********************************************************************************************/

int inGetShiftTemplate() {
    char szTemplateFileName[FILENAME_SIZE + 1];

    strcpy(szTemplateFileName, STATIC_DATA_PATH);
    strcat(szTemplateFileName, szGetShiftReportNamePrefix());
    strcat(szTemplateFileName, szGetTemplateFileNameSuffix());

    if (inSwitchTemplate(szTemplateFileName) < 0) {
        vdDisplayMessageFromFile(FORMATER_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
    }
    return(VS_SUCCESS);
}


int SHIFT_CODE_CHECK(char* a,char* b,short* c,char* d,unsigned char* e) {
    GET_VER(a, b, c, d, e);
    return 1;
}

#endif  /* SHIFT_DEFINED */

